package com.zed.api.common.param;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 提供基于某种名称前缀的子初始化参数
 *
 * @author Zed
 */
public final class SubsetParameters implements Parameters {

    private final String prefix;
    private final Parameters parameters;

    /**
     * 构造方法
     *
     * @param parameters {@link Parameters}, 初始化参数
     * @param prefix     {@link String}, 前缀
     */
    public SubsetParameters(Parameters parameters, String prefix) {
        this.parameters = Objects.requireNonNull(parameters, "\"parameters\" cannot be null.");
        this.prefix = prefix.endsWith(DOT) ?
                prefix :
                prefix.concat(DOT);
    }

    /**
     * 根据<code>name</code>获取参数值
     *
     * @param name {@link String}, 参数名
     * @return {@link String}, 参数值，参数不存在则返回null.
     */
    @Override
    public Object getParameter(String name) {
        String fullName = this.prefix.concat(name);
        return this.parameters.getParameter(fullName);
    }

    @Override
    public <T> T getParameter(String name, Class<T> requireClazz) {

        Object parameter = this.getParameter(name);

        if (parameter != null) {
            if (requireClazz.isAssignableFrom(parameter.getClass())) {
                return requireClazz.cast(parameter);
            }
        }

        return null;
    }

    /**
     * 获取所有初始化参数名称
     *
     * @return {@link List}, 列表
     */
    @Override
    public List<String> getParameterNames() {
        List<String> result = this.parameters.getParameterNames(this.prefix);
        return result.stream()
                .map(name -> name.substring(this.prefix.length()))
                .collect(Collectors.toList());
    }

    /**
     * 获取所有满足<code>prefix</code>前缀的参数名<br<
     * 如果<code>name</code>不是以"."作为结尾，方法执行时会自动添加"."后再进行比较。
     *
     * @param prefix {@link String}
     * @return {@link List}
     */
    @Override
    public List<String> getParameterNames(String prefix) {
        final String fullPrefix = prefix.endsWith(DOT) ?
                this.prefix.concat(prefix) :
                this.prefix.concat(prefix).concat(DOT);
        List<String> result = this.parameters.getParameterNames(fullPrefix);
        return result.stream()
                .map(name -> name.substring(this.prefix.length()))
                .collect(Collectors.toList());
    }

    @Override
    public String toString() {
        return "SubInitParameters{" +
                "prefix='" + prefix + '\'' +
                ", parameters=" + parameters +
                '}';
    }
}
